package com.yangxk.kadmin.web.module.system.service.impl;

import com.yangxk.kadmin.common.base.AbstractService;
import com.yangxk.kadmin.common.support.BeanValidator;
import com.yangxk.kadmin.common.support.generator.IdGenerator;
import com.yangxk.kadmin.common.util.StringUtil;
import com.yangxk.kadmin.common.util.ValidUtil;
import com.yangxk.kadmin.web.common.enumeration.ResponseCode;
import com.yangxk.kadmin.web.module.system.form.AuthForm;
import com.yangxk.kadmin.web.module.system.form.AuthQueryForm;
import com.yangxk.kadmin.web.module.system.mapper.AuthMapper;
import com.yangxk.kadmin.web.module.system.po.Auth;
import com.yangxk.kadmin.web.module.system.pojo.AuthQuery;
import com.yangxk.kadmin.web.module.system.service.AuthService;
import com.yangxk.kadmin.web.module.system.vo.AuthTree;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class AuthServiceImpl extends AbstractService<Auth, Long> implements AuthService {

    public static final Long ROOT_PARENT_ID = 0L;

    @Autowired
    private AuthMapper authMapper;

    /**
     * 查询权限树
     * create by yangxk on 2018/10/19 15:50
     */
    @Override
    public List<AuthTree> queryAuthTree() {
        List<Auth> authList = authMapper.queryAll();
        return transform2Tree(authList, ROOT_PARENT_ID);
    }

    /**
     * 根据父节点条件查询
     * create by yangxk on 2018/10/19 15:17
     */
    @Override
    public List<Auth> queryByParent(AuthQueryForm queryForm) {
        BeanValidator.check(queryForm);
        AuthQuery query = new AuthQuery();
        BeanUtils.copyProperties(queryForm, query);

        return authMapper.queryByParent(query);
    }

    @Override
    @Transactional
    public long addAuth(AuthForm authForm) {
        BeanValidator.check(authForm);
        Auth auth = new Auth();

        BeanUtils.copyProperties(authForm, auth);
        auth.setId(IdGenerator.getId());
        auth.setCreateTime(new Date());
        auth.setUpdateTime(new Date());

        authMapper.insertSelective(auth);
        return auth.getId();
    }

    @Override
    @Transactional
    public void updateAuth(AuthForm authForm) {
        BeanValidator.check(authForm);
        Auth before = authMapper.selectByPrimaryKey(authForm.getId());
        ValidUtil.checkNotNull(before, ResponseCode.UPDATE_CHECK_NULL.getMessage());

        Auth auth = new Auth();
        BeanUtils.copyProperties(authForm, auth);
        auth.setUpdateTime(new Date());

        authMapper.updateByPrimaryKeySelective(auth);
    }

    @Override
    @Transactional
    public void deleteAuth(long id) {
        List<Auth> authList = new ArrayList<>();
        recursiveQuery(id, authList);

        Set<Long> ids = authList.stream().map(auth -> auth.getId()).collect(Collectors.toSet());
        ids.add(id);
        // 批量删除权限
        authMapper.deleteBatch(new ArrayList<>(ids));
        // 删除角色中被分配的对应的权限
        authMapper.deleteRoleAuth(new ArrayList<>(ids));
    }

    @Override
    @Transactional
    public void deleteAuth(String ids) {
        ValidUtil.checkNotNull(ids, ResponseCode.ILLEGAL_PARAM.getMessage());
        String[] arr = StringUtil.str2Arr(ids);
        for (String id : arr) {
            this.deleteAuth(Long.valueOf(id));
        }
    }

    /**=============================用户权限相关查询==========================================*/
    /**
     * 根据用户ID查询权限
     * create by yangxk on 2018/10/19 15:15
     */
    @Override
    public List<Auth> queryUserAuth(long userId) {
        return authMapper.findAuthByUserId(userId);
    }

    /**
     * 根据用户ID查询权限树
     * create by yangxk on 2018/10/19 15:17
     */
    @Override
    public List<AuthTree> queryUserAuthTree(long userId) {
        List<Auth> authList = queryUserAuth(userId);
        return transform2Tree(authList, ROOT_PARENT_ID);
    }

    /**
     * 查询所有权限
     *
     * create by yangxk on 2018/10/19 16:47
     */
    @Override
    public List<Auth> queryAllAuth() {
        return authMapper.queryAll();
    }


    /**============================私有方法=========================================*/

    /**
     * 将List<Auth>转换为树形结构List<AuthTree>
     * create by yangxk on 2018/9/21 16:04
     */
    private List<AuthTree> transform2Tree(List<Auth> authList, long parentId) {
        List<AuthTree> result = new ArrayList<>();
        AuthTree vo = null;
        for (Auth auth : authList) {
            if (parentId == auth.getParentId()) {
                vo = new AuthTree();
                BeanUtils.copyProperties(auth, vo);

                // 递归寻找子节点
                vo.setChildren(transform2Tree(authList, auth.getId()));

                result.add(vo);
            }
        }

        return result;
    }

    /**
     * 递归查询子节点
     * @param parentId 开始查询的父节点ID
     * @param result   查询后的结果集
     * create by yangxk on 2018/10/19 15:26
     */
    private void recursiveQuery(long parentId, List<Auth> result) {
        List<Auth> auths = authMapper.queryByParentId(parentId);
        if (!ValidUtil.isEmpty(auths)) {
            result.addAll(auths);
            for (Auth auth : auths) {
                recursiveQuery(auth.getId(), result);
            }
        }
    }

}
